#ifndef EVENTLOOP_H
#define EVENTLOOP_H


#include "Channel.h"
#include "Dispatcher.h"

#include <sys/socket.h>
#include <thread>
#include <queue>
#include <map>
#include <mutex>
#include <string.h>
#include <assert.h>

using namespace std;

enum class ElemType:char{ADD, DELETE, MODIFY};

struct ChannelElement {
    ElemType type;
    Channel* channel;
};

class Dispatcher;
class EventLoop
{
public:
    EventLoop();

    EventLoop(const string threadName);

    ~EventLoop();

    int run();

    int readMessage();

    int addTask(Channel* channel, ElemType type);

    int processTaskQ();

    int add(Channel* channel);

    int remove(Channel* channel);

    int modify(Channel* channel);

    int eventActive(int fd, int event);

    int freeChannel(Channel* channel);

    inline thread::id getThreadID() {
        return m_threadID;
    }
    inline string getThreadName() {
        return m_threadName;
    }

private:
    void taskWakeup();

private:
    bool m_isQuit;

    Dispatcher* m_dispatcher;

    queue<ChannelElement*> m_taskQ;

    map<int, Channel*> m_channelMap;

    thread::id m_threadID;

    string m_threadName;

    mutex m_mutex;

    int m_socketPair[2];
};

#endif // EVENTLOOP_H
